using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace CosyTrade.Data
{
    [Serializable]
    public class BusinessBindingList : BindingList<BusinessBase>, IBusiness,IORM
    {
        [NonSerialized]
        private readonly Stack<BusinessBase> _DeletedItems = new Stack<BusinessBase>();

        public BusinessBindingList(IList<BusinessBase> list)
            : base(list)
        {
            _BusinessBindingList();
        }

        public BusinessBindingList()
        {
            _BusinessBindingList();
        }

        private void _BusinessBindingList()
        {
            AllowEdit = true;
            AllowNew = true;
            AllowRemove = true;
        }
        
 
        protected override void RemoveItem(int index)
        {
            BusinessBase item = this[index];
            item.IsDelete = true;
            _DeletedItems.Push(item);
            base.RemoveItem(index);
        }

        public void AcceptChanges()
        {
            _DeletedItems.Clear();
            foreach (BusinessBase item in this) item.AcceptChanges();
        }

        public void RejectChanges()
        {
            for (int i = Count - 1; i >= 0; i--)
            {
                if (this[i].IsNew) RemoveAt(i);
                else if (this[i].IsModify) this[i].RejectChanges();
            }

            while (_DeletedItems.Count > 0)
            {
                BusinessBase item = _DeletedItems.Pop();
                if (!item.IsNew)
                {
                    item.RejectChanges();
                    Add(item);
                }
            }
            _DeletedItems.Clear();
        }

        public IORM GetChanges()
        {
            ORMCollection ormCollection = new ORMCollection();
            UndoableBase[] deleteItems = _DeletedItems.ToArray();

            foreach (BusinessBase deleteItem in deleteItems)
                if (!deleteItem.IsNew) ormCollection.Add(deleteItem);

            foreach (BusinessBase item in this)
                if (item.IsNew || item.IsModify) ormCollection.Add(item);

            return ormCollection;
        }

        public void AffrimChanges()
        {
            foreach (BusinessBase item in this) item.AffrimChanges();
        }

        public bool IsChange
        {
            get
            {
                foreach (IBusiness bussines in this)
                {
                    if (bussines.IsChange) return true;
                }
                return _DeletedItems.Count > 0;
            }
        }
    }

    [Serializable]
    public class BusinessBindingList<T>:BindingList<T>,IBusiness,IORM where T:BusinessBase
    {
        [NonSerialized]
        private readonly Stack<T> _DeletedItems = new Stack<T>();

        public BusinessBindingList(IList<T> list) : base(list)
        {
            _musinessBindingList();
        }

        public BusinessBindingList()
        {
            _musinessBindingList();
        }

        private void _musinessBindingList()
        {
            AllowEdit = true;
            AllowNew = true;
            AllowRemove = true;
        }

        protected override void RemoveItem(int index)
        {
            T item = this[index];
            item.IsDelete = true;
            _DeletedItems.Push(item);
            base.RemoveItem(index);
        }

        public void AcceptChanges()
        {
            _DeletedItems.Clear();
            foreach (T item in this) item.AcceptChanges();
        }

        public void RejectChanges()
        {
            for (int i = Count - 1; i >= 0; i--)
            {
                if (this[i].IsNew) RemoveAt(i);
                else if (this[i].IsModify) this[i].RejectChanges();
            }

            while (_DeletedItems.Count > 0)
            {
                T item = _DeletedItems.Pop();
                if (!item.IsNew)
                {
                    item.RejectChanges();
                    Add(item);
                }
            }
            _DeletedItems.Clear();
        }

        public void AffrimChanges()
        {
            foreach (T item in this) item.AffrimChanges();
        }

        public bool IsChange
        {
            get
            {
                foreach (IBusiness bussines in this)
                {
                    if (bussines.IsChange) return true;
                }
                return _DeletedItems.Count > 0;
            }
        }

        public IORM GetChanges()
        {
            BusinessBindingList<T> ormCollection = new BusinessBindingList<T>();

            foreach (T deleteItem in _DeletedItems)
                if (!deleteItem.IsNew) ormCollection.Add(deleteItem);

            foreach (T item in this)
            {
                item.AffrimChanges();
                if (item.IsChange) ormCollection.Add((T) item.GetChanges());
            }
            return ormCollection;
        }
    }

}